﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using IronSuit.DataMap;
using IronSuit.Tools.Properties;
using IronSuit.Utility;
using MySql.Data.MySqlClient;

namespace IronSuit.Tools.Entity
{
	public partial class EntityForm : Form
	{
		public EntityForm()
		{
			InitializeComponent();
		}
		private void EntityForm_Load(object sender, EventArgs e)
		{
			InitAuth();
		}
		private void InitAuth()
		{
			if (RBAuthWin.Checked)
			{
				TBUserName.Enabled = false;
				TBPassword.Enabled = false;
			}
			else
			{
				TBUserName.Enabled = true;
				TBPassword.Enabled = true;
			}
		}

		private void RBAuthWin_CheckedChanged(object sender, EventArgs e)
		{
			InitAuth();
		}

		private void RBAuthSql_CheckedChanged(object sender, EventArgs e)
		{
			InitAuth();
		}
		List<ColumnStruct> ColumnList = new List<ColumnStruct>();
		List<ColumnStruct> KeyColumnList = new List<ColumnStruct>();
		private void BtnCreat_Click(object sender, EventArgs e)
		{
			TBCode.Text = "";
			SetColumnList();
			string EntityCode = Resources.DataMap;
			EntityCode = EntityCode.Replace("{Tablename}", TBTableName.Text);
			EntityCode = EntityCode.Replace("{ClassName}", ISUtility.Pascal(TBTableName.Text));
			EntityCode = EntityCode.Replace("{KeyInput}", GetKeyInput());
			EntityCode = EntityCode.Replace("{KeyEquals}", GetKeyEquals());
			EntityCode = EntityCode.Replace("{KedAdd}", GetKedAdd());
			EntityCode = EntityCode.Replace("{Property}", GetProperty());

			TBCode.Text = EntityCode;
		}

		private string GetKedAdd()
		{
			string strOut = "";
			foreach (ColumnStruct C in KeyColumnList)
			{
				strOut = strOut + "KeyFieldList.Add(\"" + C.Name + "\");" + "\r\n";
			}
			return strOut;
		}

		private string GetProperty()
		{
			StringBuilder strOut = new StringBuilder();
			foreach (ColumnStruct C in ColumnList)
			{
				string tStr = @"		public {1} {2}
		{4}
			get
			{4}
				return GetFieldValue(""{0}"", {3});
			{5}
			set
			{4}
				SetFieldValue(""{0}"", value);
			{5}
		{5}";
				strOut.AppendLine(string.Format(tStr, C.Name, C.ClassType, C.PascalName, C.Default, "{", "}"));
			}
			return strOut.ToString();
		}

		private string GetKeyEquals()
		{
			string strOut = "";
			foreach (ColumnStruct C in KeyColumnList)
			{
				strOut = strOut + "this." + C.PascalName + "=" + C.CamelName + ";\r\n";
			}
			return strOut;
		}

		private string GetKeyInput()
		{
			string strOut = "";
			foreach (ColumnStruct C in KeyColumnList)
			{
				strOut = strOut + C.ClassType + " " + C.CamelName + ",";
			}
			strOut = strOut.TrimEnd(',');
			return strOut;
		}

		private void SetColumnList()
		{
			ColumnList.Clear();
			KeyColumnList.Clear();
			if (MSSqlRB.Checked)
			{
				DataSet DS;
				using (DBFactory DBF = new DBFactory())
				{
					string sql = @"SELECT        sys.syscolumns.name, sys.systypes.name AS Expr1, sys.syscolumns.isnullable, sys.syscolumns.length, sys.extended_properties.value
FROM            sys.syscolumns INNER JOIN
                         sys.systypes ON sys.syscolumns.xusertype = sys.systypes.xusertype LEFT OUTER JOIN
                         sys.extended_properties ON sys.extended_properties.major_id = sys.syscolumns.id AND sys.extended_properties.minor_id = sys.syscolumns.colid
WHERE        (sys.syscolumns.id = OBJECT_ID('{0}'));EXEC sp_pkeys @table_name='{0}'";
					DS = DBF.ExecQuerySql(string.Format(sql, TBTableName.Text), null);
				}
				DataTable DT = DS.Tables[0];
				DataTable KeyDT = DS.Tables[1];
				foreach (DataRow DR in DT.Rows)
				{
					ColumnStruct CS = new ColumnStruct();
					CS.Name = DR[0].ToString();
					CS.Type = DR[1].ToString();
					CS.Isnullable = (int)DR[2];
					CS.Length = int.Parse(DR[3].ToString());
					CS.Desc = DR[4].ToString();
					ColumnList.Add(CS);
					foreach (DataRow KeyDR in KeyDT.Rows)
					{
						if (CS.Name == KeyDR[3].ToString())
							KeyColumnList.Add(CS);
					}
				}
			}
			if (MySqlRB.Checked)
			{
				DataSet mySqlDS;
				using (DBFactory DBF = new DBFactory())
				{
					string sql = @"show columns from {0}";
					mySqlDS = DBF.ExecQuerySql(string.Format(sql, TBTableName.Text));
				}
				foreach (DataRow DR in mySqlDS.Tables [0].Rows)
				{
					ColumnStruct CS = new ColumnStruct();
					string typestr = DR[1].ToString().Split('(')[0];
					CS.Name = DR[0].ToString();
					CS.Type = typestr;
					CS.Isnullable = (DR[2].ToString().Equals("YES")?1:0);
					CS.Length =0;
					CS.Desc = "";
					ColumnList.Add(CS);

					if (DR[3].ToString().Equals("PRI"))
						KeyColumnList.Add(CS);
					
				}
			}
		}


	}
	public struct ColumnStruct
	{
		public string Name;
		public string Type;
		public int Isnullable;
		public int Length;
		public string Desc;

		public string ClassType
		{
			get
			{
				switch (Type)
				{
					case "char":
					case "nchar":
					case "varchar":
					case "nvarchar":
					case "text":
					case "ntext":
						return "string";
					case "datetime":
					case "smalldatetime":
						return "DateTime";
					case "bit":
						return "bool";
					case "binary":
						return "byte[]";
					case "decimal":
						return "decimal";
					case "real":
					case "float":
						return "float ";
					case "int":
					case "smallint":
						return "int";
					case "tinyint":
						return "byte";
					case "uniqueidentifier":
						return "Guid";
					default:
						return "string";
				}
			}
		}
		public string Default
		{
			get
			{
				switch (Type)
				{
					case "char":
					case "nchar":
					case "varchar":
					case "nvarchar":
					case "text":
					case "ntext":
						return "\"\"";
					case "datetime":
					case "smalldatetime":
						return "DateTime.MinValue";
					case "bit":
						return "false";
					case "binary":
						return "byte[]";
					case "decimal":
						return "decimal.MinValue";
					case "real":
					case "float":
						return "float.MinValue";
					case "int":
					case "smallint":
						return "int.MinValue";
					case "tinyint":
						return "0";
					case "uniqueidentifier":
						return "Guid .Empty";
					default:
						return "\"\"";
				}
			}
		}
		public string PascalName
		{
			get
			{
				return ISUtility.Pascal(Name);
			}
		}
		public string CamelName
		{
			get
			{
				return ISUtility.Camel(Name);
			}
		}
	}
}
